package ar.unsam.tp.programa

import ar.unsam.tp.excepciones.NoSeJuegaException
import java.util.ArrayList
import java.util.List
import ar.unsam.tp.infraccion.SinReemplazo
import ar.unsam.tp.interfaces.Observable
import ar.unsam.tp.managers.ManagerJugadores
import ar.unsam.tp.managers.ManagerAspirantes
import ar.unsam.tp.managers.ManagerCalificaciones

class Partido implements Observable {
	public List<Jugador> jugadoresCandidatos = new ArrayList<Jugador>
	public List<Jugador> jugadoresQueJueganSeguro = new ArrayList<Jugador>
	@Property public Administrador admin = new Administrador(new ManagerJugadores(this), new ManagerAspirantes(this), new ManagerCalificaciones())
	@Property String lugar

	override void notificarJugador(Jugador jugador) {
		jugadoresCandidatos.filter[j|j != jugador].forEach[it.enviarMensaje("Se anoto " + jugador.nombre)]
	}

	override void notificarAdminCompleto(Administrador adm) {
		adm.enviarMensaje("Equipo completo")
	}

	override void notificarAdminIncompleto(Administrador adm) {
		adm.enviarMensaje("Equipo dejo de estar completo")
	}

	override void alta(Jugador jugador) {
		admin.managerJugadores.verificaAltaJugador(jugador)
		jugadoresCandidatos.add(jugador)
		admin.managerJugadores.definirJugadores
		notificarJugador(jugador)
		if (jugadoresCandidatos.size == 10)
			notificarAdminCompleto(admin)
	}

	override void baja(Jugador jugador) {
		admin.managerJugadores.verificaBajaJugador(jugador)
		jugadoresCandidatos.remove(jugador)
		admin.managerJugadores.definirJugadores
		jugador.setInfraccion(new SinReemplazo)
		jugador.penaliza()
		if (jugadoresCandidatos.size == 9)
			notificarAdminCompleto(admin)
	}

	def void reemplazo(Jugador saliente, Jugador ingresante) {
		admin.managerJugadores.verificaReemplazoJugador(ingresante)
		jugadoresCandidatos.set(jugadoresCandidatos.indexOf(saliente), ingresante)
		notificarJugador(ingresante)
	}

	def boolean seJuega() {
		admin.managerJugadores.definirJugadores
		if (jugadoresQueJueganSeguro.size < 10) {
			throw new NoSeJuegaException("Numero de jugadores insuficiente. Partido suspendido")
		}
		true
	}
	
	def verificarSiJuegaSeguro(Jugador jugador) {
		this.jugadoresQueJueganSeguro.contains(jugador)
	}

	def void mostrarErrorEnConsola(String mensaje) {
		println(mensaje)
	}
}